﻿using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.TestManagement.Client;

namespace TFSTools.TFSLibrary.TestManagement
{
    public sealed class TFSTestCase : TFSServerEntity
    {
        private ITestCase serverTestCase;
        private TFSTestActionCollection testActionList;

        private TFSWorkItem tfsWorkItem;

        private TFSTestIterationRowCollection iterationData;
        private TFSTestIterationRow selectedIteration;
        private bool includeParameterNameInIterationText;
        private bool includeDelimiterInIterationText;

        private StepCommentXml stepCommentXml;

        internal TFSTestCase(ITFSConnection connection, ITestCase testCase)
            : base(connection)
        {
            this.serverTestCase = testCase;
            this.tfsWorkItem = new TFSWorkItem(connection, testCase.WorkItem);
        }

        internal ITestCase ServerTestCase { get { return this.serverTestCase; } }

        public bool IncludeParameterNameInIterationText 
        {
            get { return this.includeParameterNameInIterationText; } 
            set 
            {
                this.includeParameterNameInIterationText = value;
                this.SetSelectedIteration(this.selectedIteration, value, this.includeDelimiterInIterationText);
            } 
        }

        public bool IncludeDelimiterInIterationText
        {
            get { return this.includeDelimiterInIterationText; }
            set
            {
                this.includeDelimiterInIterationText = value;
                this.SetSelectedIteration(this.selectedIteration, this.includeParameterNameInIterationText, value);
            }
        }

        public TFSTestIterationRow SelectedIteration
        {
            get { return this.selectedIteration; }
            set
            {
                this.selectedIteration = value;
                this.SetSelectedIteration(value, this.IncludeParameterNameInIterationText, this.IncludeDelimiterInIterationText);
            }
        }

        private void SetSelectedIteration(TFSTestIterationRow value, bool includeParamName, bool includeDelimiter)
        {
            if (value != null)
            {
                foreach (var testAction in this.TestActionList)
                {
                    if (testAction is TFSTestStep)
                    {
                        ((TFSTestStep)testAction).UpdateSelectedIteration(value, includeParamName, includeDelimiter);
                    }
                }
            }
        }

        public TFSTestIterationRowCollection IterationData
        {
            get
            {
                if (this.iterationData == null)
                {
                    this.iterationData = TFSTestIterationRowCollection.Create(this.serverTestCase);
                }

                return this.iterationData;
            }
        }

        public TFSTestActionCollection TestActionList
        {
            get 
            {
                if (this.testActionList == null)
                {
                    this.testActionList = TFSTestActionCollection.Create(this);
                }

                return this.testActionList; 
            }
        }

        public TFSWorkItem WorkItem
        {
            get { return this.tfsWorkItem; }
        }

        public int Id { get { return this.serverTestCase.Id; } }

        public string Title
        {
            get { return this.serverTestCase.Title; }
            set { this.serverTestCase.Title = value; }
        }

        public string State
        {
            get { return this.serverTestCase.State; }
            set { this.serverTestCase.State = value; }
        }

        public string Reason
        {
            get { return this.serverTestCase.Reason; }
            set { this.serverTestCase.Reason = value; }
        }

        public string Description
        {
            get { return this.serverTestCase.Description; }
            set { this.serverTestCase.Description = value; }
        }

        public string StepCommentsFieldReferenceName
        {
            get
            {
                return this.StepCommentXmlBuilder.FieldReferenceName;
            }

            set
            {
                //this.StepCommentXmlBuilder.FieldReferenceName = value;
                this.stepCommentXml = new StepCommentXml(this, value);
            }
        }

        private StepCommentXml StepCommentXmlBuilder
        {
            get 
            {
                if (this.stepCommentXml == null)
                {
                    this.stepCommentXml = new StepCommentXml(this, StepCommentXml.DefaultFieldReferenceName);
                }

                return this.stepCommentXml; 
            }
        }

        public bool IsCommentFieldExistsInTFS
        {
            get { return this.StepCommentXmlBuilder.IsCommentFieldExists; }
        }

        public void Save()
        {
            this.stepCommentXml.SaveStepComments();
            this.ServerTestCase.Save();
        }

        public override string ToString()
        {
            return this.serverTestCase.ToString();
        }
    }

    public sealed class TFSTestCaseCollection : TFSServerEntityCollection<TFSTestCase>
    {
        public TFSTestCaseCollection(ITFSConnection connection)
            : base(connection)
        {
        }

        public TFSTestCaseCollection(ITFSConnection connection, IList<TFSTestCase> list)
            : base(connection, list)
        {
        }

        public TFSTestCaseCollection(ITFSConnection connection, int capacity)
            : base(connection, capacity)
        {
        }

        internal static TFSTestCaseCollection Create(ITFSConnection connection, ITestCaseCollection collection)
        {
            var list = new List<TFSTestCase>(collection.Count);

            foreach (ITestCase testCase in collection)
            {
                list.Add(new TFSTestCase(connection, testCase));
            }

            return new TFSTestCaseCollection(connection, list);
        }

        internal static TFSTestCaseCollection Create(ITFSConnection connection, ITestSuiteEntryCollection collection)
        {
            var list = new List<TFSTestCase>(collection.Count);

            foreach (ITestSuiteEntry testSuiteEntry in collection)
            {
                list.Add(new TFSTestCase(connection, testSuiteEntry.TestCase));
            }

            return new TFSTestCaseCollection(connection, list);
        }
    }
}
